package com.youlai.boot.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.youlai.boot.system.model.dto.PatientDTO;
import com.youlai.boot.system.model.entity.User;
import com.youlai.boot.system.service.UserService;
import com.alibaba.excel.util.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.system.mapper.PatientMapper;
import com.youlai.boot.system.service.PatientService;
import com.youlai.boot.system.model.entity.Patient;
import com.youlai.boot.system.model.form.PatientForm;
import com.youlai.boot.system.model.query.PatientQuery;
import com.youlai.boot.system.model.vo.PatientVO;
import com.youlai.boot.system.converter.PatientConverter;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;

/**
 * 患者信息服务实现类
 *
 * @author
 * @since 2025-03-03 16:25
 */
@Service
@RequiredArgsConstructor
public class PatientServiceImpl extends ServiceImpl<PatientMapper, Patient> implements PatientService {

    private final PatientConverter patientConverter;
    @Autowired
    private PatientMapper patientMapper;
    private final UserService userService;
    private Integer cachedSurgeryCount;//缓存过去7天手术数量统计结果

    /**
     * 获取患者信息分页列表
     *
     * @param queryParams 查询参数
     * @return {@link IPage<PatientVO>} 患者信息分页列表
     */
    @Override
    public IPage<PatientVO> getPatientPage(PatientQuery queryParams) {
        // 创建 QueryWrapper 动态构建查询条件
        QueryWrapper<Patient> queryWrapper = new QueryWrapper<>();

        // 根据患者姓名模糊查询
        if (StringUtils.isNotBlank(queryParams.getPatientName())) {
            queryWrapper.like("patient_name", queryParams.getPatientName());
        }

        // 根据主治医生精确查询
        if (StringUtils.isNotBlank(queryParams.getAttendingDoctor())) {
            queryWrapper.eq("attending_doctor", queryParams.getAttendingDoctor());
        }

        // 根据诊断结果模糊查询
        if (StringUtils.isNotBlank(queryParams.getDiagnosi())) {
            queryWrapper.like("diagnosi", queryParams.getDiagnosi());
        }

        // 根据手术名称模糊查询
        if (StringUtils.isNotBlank(queryParams.getOperation())) {
            queryWrapper.like("operation", queryParams.getOperation());
        }

        // 如果有时间范围查询的需求，可以在这里添加类似前面示例中的逻辑
        // 时间范围查询
        if (queryParams.getAddtime() != null && queryParams.getAddtime().size() == 2) {
            String startTime = queryParams.getAddtime().get(0) + " 00:00:00";
            String endTime = queryParams.getAddtime().get(1) + " 23:59:59";
            queryWrapper.between("addtime", startTime, endTime);
        }

        // 按 id 排序
        queryWrapper.orderByDesc("id");

        // 获取分页参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();


        Page<Patient> page = new Page<>(pageNum, pageSize);
        // 执行分页查询
        Page<Patient> data = this.page(page, queryWrapper);

        // 如果有数据，则进行进一步处理
        if (data != null && data.getTotal() > 0) {
            List<Patient> records = data.getRecords();

            // 提取所有不同的 attending_doctor 字段值
            List<String> doctorIds = records.stream()
                    .map(Patient::getAttendingDoctor)
                    .filter(StringUtils::isNotBlank)
                    .distinct()
                    .collect(Collectors.toList());
            if(doctorIds.size()== 0){
                return patientConverter.toPageVO(data);
            }
            // 查询这些医生的详细信息
            List<User> userList = userService.list(new QueryWrapper<User>().in("id", doctorIds));
            Map<Long, String> doctorMap = userList.stream()
                    .collect(Collectors.toMap(User::getId, User::getNickname));

            // 遍历所有记录，将 attending_doctor 字段从医生 ID 更新为医生姓名
            for (Patient record : records) {
                String attendingDoctor = record.getAttendingDoctor();
                if (StringUtils.isNotBlank(attendingDoctor)) {
                    Long doctorId = Long.parseLong(attendingDoctor);
                    record.setAttendingDoctor(doctorMap.get(doctorId));
                }
            }
        }

        // 将查询结果转换为 VO 对象并返回
        return patientConverter.toPageVO(data);
    }

    /**
     * 获取患者信息表单数据
     *
     * @param id 患者信息ID
     * @return
     */
    @Override
    public Patient getPatientFormData(Long id) {
        Patient entity = this.getById(id);
        return patientConverter.toForm(entity);
    }

    /**
     * 新增患者信息
     *
     * @param formData 患者信息表单对象
     * @return
     */
    @Override
    public boolean savePatient(PatientForm formData) {
        Patient entity = patientConverter.toEntity(formData);
        formData.setArchive(0);
        return this.save(entity);
    }

    /**
     * 更新患者信息
     *
     * @param id   患者信息ID
     * @param formData 患者信息表单对象
     * @return
     */
    @Override
    public boolean updatePatient(Long id,PatientForm formData) {
        Patient entity = patientConverter.toEntity(formData);
        return this.updateById(entity);
    }

    /**
     * 删除患者信息
     *
     * @param id 患者信息ID，多个以英文逗号(,)分割
     * @return
     */
    @Override
    public boolean deletePatients(String id) {
        Assert.isTrue(StrUtil.isNotBlank(id), "删除的患者信息数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(id.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }

    /**
     * 单个归档
     * @param id
     * @param archive
     * @return
     */
    @Override
    public boolean updateArchive(Long id, Integer archive) {
        UpdateWrapper<Patient> patientUpdateWrapper = new UpdateWrapper<>();
        patientUpdateWrapper.eq("id" ,id);
        Patient patient = new Patient();
        patient.setArchive(archive);
        return patientMapper.update(patient,patientUpdateWrapper) > 0 ;
    }

    /**
     * 批量归档
     * @param id
     * @param archive
     * @return
     */
    @Override
    public boolean batchUpdateArchiveStatus(List<Long> id, Integer archive) {
        if(id == null || id.isEmpty() ) {
            return false;
        }

        UpdateWrapper<Patient> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id",id);

        Patient patient = new Patient();
        patient.setArchive(archive);

        return patientMapper.update(patient,updateWrapper) >0;
    }



//    @Override
//    public List<Patient> getArchiveTasks() {
//        QueryWrapper<Patient> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("archive",1);
//        return this.list(queryWrapper);
//    }

    @Override
    public IPage<PatientVO> getArchivePage(PatientQuery queryParams) {
        Page<PatientVO> pageVO = this.baseMapper.selectTasksByArchiveStatus(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }
    /**
     * 获取性别统计
     * @return
     */
    @Override
    public List<Map<String, Object>> getGenderCount() {
        return patientMapper.getGenderCount();
    }
//    @Scheduled(cron = "0/1 * * * * ?") // 每秒执行一次
//    public void countPatientsEverySecond() {
//        int totalPatients = getTotalDoctors();
//        System.out.println("当前时间：" + java.time.LocalDateTime.now() + "，患者总数：" + totalPatients);
//    }
    @Override
    public int getTotalDoctors() {

        return Math.toIntExact(patientMapper.selectCount(null));
    }

    /**
     * 统计手术总数
     * @return
     */
    @Override
    public int countOperationNumber() {
        QueryWrapper<Patient> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNotNull("operation").ne("operation", "");
        Long count = patientMapper.selectCount(queryWrapper);
        return Math.toIntExact(count);
    }

    /**
     * 统计最近7天手术数量
     * @return
     */
    @Override
    public Integer countSurgeriesInLastSevenDays() {
        if (cachedSurgeryCount == null) {
            updateSurgeryCount();
        }
        return cachedSurgeryCount;
    }
    @Scheduled(cron = "0 0 3 * * ?")
    public void updateSurgeryCount() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 计算七天前的时间
        LocalDateTime sevenDaysAgo = now.minus(7, ChronoUnit.DAYS);

        // 构建查询条件
        QueryWrapper<Patient> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("operation_date", sevenDaysAgo);
        queryWrapper.le("operation_date", now);

        // 统计符合条件的手术数量，返回值是 Long 类型
        Long count = baseMapper.selectCount(queryWrapper);
        // 将 Long 类型转换为 Integer 类型
        cachedSurgeryCount = count.intValue();
    }

    /**
     * 过去一周的患者数量
     * @param now
     * @return
     */
    @Override
    public Integer countPatientsByDateRange(LocalDateTime now) {
        LocalDateTime startOfPeriod = now.minusDays(7).withHour(0).withMinute(0).withSecond(0).withNano(0);

// 结束时间为当前时间
        LocalDateTime endOfPeriod = now.withHour(0).withMinute(0).withSecond(0).withNano(0);
        Long count = patientMapper.countPatientsByDateRange(startOfPeriod,endOfPeriod);

// 查询并返回该时间段内的患者总数
        return Math.toIntExact(count.intValue());
    }

    /**
     * 年龄
     *
     * @return
     */
    @Override
    public List<PatientDTO> getPatientCountByAgeGroups() {
        return patientMapper.countPatientsByAgeGroups();
    }

    @Scheduled(cron = "0 0 8 ? * MON")
// @Scheduled(cron = "0/1 * * * * ?")
    public void weeklyCount(){
        long count = countPatientsByDateRange(LocalDateTime.now());
        System.out.println("当前时间" + LocalDateTime.now() + "过去一周患者总数：" + count);

    }

}
